************************* Use C-Pg Up to return *******************************
********************* Use Pg Up and Pg Dn to scroll ***************************
*************************** Use C-s to search *********************************
Copyright (C) 1993 Leon van Dommelen      There is no warranty on this software
Library letter: M (MINTED.ED)

				 Modify

This subject discusses the ways you can change Freemacs to your liking.


Topics:				Description
-------------------------------------------------------------------------------

Intro				What is Mint

Simple Changes			Changing keys or defaults
- Setting Defaults		Change defaults for the editor
- Changing Keys			Modifying the keyboard layout

Basics of Mint			How the Mint language works
- Example			A very simple change to a command
- Simple Mint Code		And F2, add, announce, pause, bell
- Defining Strings		And define string, get string
- Partial Strings		And get one, get n, restore string
- Searching Strings		And first match
- Functions			And current time, Umodified
- Comparing Strings		And equality, greater than
- Recursion			Repeat yourself and k-see
- Arguments			And make parameter, insert string
- Editing Strings		Make parameter once more
- Neutral Strings		And base conversion
- Managing Strings		And list strings, erase strings
- Marks				And set point, set mark, put mark, read to mark
- Searching			And look pattern, look
- Conclusion			Some important hints

Mint Library			Summary of commands used to edit functions
- Initialize			Not usually necessary
- Execute			Execute functions
- Edit				Edit functions
- Debug				Finding bugs
- Syntax			Not recommended
- Manage			Managing definitions
- Erase				Erasing functions

Mint Notes			Some helpful programming notes
- Reserved Names		Names not to be used
- Functions			Conventions for library functions
- General Purpose		Useful defined functions
- Initialization		How Freemacs initializes itself
- Buffers			How buffers are defined
- Libraries			How libraries of functions are defined
- I/O				How I/O is performed
- Shell				How to shell to DOS

Browse Files			How to create your own Browse (Help) files
- File Format			How the files should look
  - Headers			Header formats
    - Subjects			Highest level header
    - Topics			Second level header
    - Subtopics			Third level header
    - Items			Fourth level header
    - Subitems			Lowest level header
  - Contents Tables		Format of contents tables
  - Pointer Lines		Format of pointer lines
  - Other Requirements		Other requirements to the file
- Browse Command		Creating a Freemacs command to browse files


				= Intro =
-------------------------------------------------------------------------------

This topic explains why and how to modify Freemacs.

Freemacs is fully programmable: you can add whatever you like, or change
whatever you don't like.  It is unlike other programming you may be used to,
and I think it is fun.  One of the nice things is that you get an immediate
response to whatever you do.

All of the commands in Freemacs are written in a text oriented language called
Mint.  Mint includes build in primitive functions that allow you to perform
such tasks as move the cursor or load a file.  By clever use of the Mint
language, you can perform complex tasks quite easily.


			   = Simple Changes =
-------------------------------------------------------------------------------

This topic discusses how you can make simple changes to the editor without
knowing much about Mint programming.

Setting Defaults:
-----------------

Freemacs has a list of options that allow you to change the editor defaults.
Suppose you want to force Freemacs to create .BAK backup files whenever
it saves a file using C-x s or C-x C-s.  The command M-x set-some-options
opens up a menu from which you would select the `Always backup' item.  (The
item will be on the second screen; press Pg Dn first.)  Answer Y on the
query whether to change the item and it will be changed.  When you exit Emacs,
you will be asked whether you want to save the changed editor. Answer Yes to
make the change permanent.

See command:	set-some-options

If you get some more experience, you might instead change options directly
by editing them.  This would be done with M-x edit-options.

See command:	edit-options

Changing Keys:
--------------

Suppose you want to change one of keyboard keys to perform another command
than it does right now.  To be specific, let us suppose that you want to
change the <Ins> key to be the usual toggle between the overstrike and insert
modes of editing. (In insert mode, any character you type is pushed in between
the characters that are already there. In overstrike mode, it replaces the
character at the cursor.)

The basic procedure is simple: press F3 and enter the command you want the
<Ins> key to execute, followed by the <Ins> key itself.  But first, you may
want to verify that the <Ins> key is not doing anything very important right
now. Press F1 for help, select the K (key) option, and press <Ins>.  This will
tell you that the <Ins> key executes the command F:insert-line.  If you do not
know what F:insert-line does, press F1 again and select F (function).  It will
tell you that F:insert-line puts the cursor on a blank line before the current
line. Clearly not very important.

Next you have to figure out what command changes the mode from insert to
overstrike.  One way to find it would be to press F1 twice and select help
on inserting text from the Summary of Freemacs functions.  Or you could
press F1 B to list all existing key definitions and notice that the C-Ins
key is bound to something called `F:overwrite-mode'.  Or you could search
for commands that contain the string `over' by using F1 A over. Anyway, having
found F:overwrite-mode, you can call up its docs using F1 f and verify that it
is indeed the desired function.

Now press F3 overwrite-mode Return, followed by <Ins> to change the definition.
See key:	F3		for the docs on bind-to-key
See command:	copy-key	on how to simply copy C-Ins to Ins

You can already create a `game' at this time, by defining the <a> key as
ring-the-bell.  The game is to write a description of given topic without ever
using the letter a.  Whenever you try to use the letter a, the bell will sound.

Of course, if you want to do much with Emacs after this, you better allow
the <a> key to insert an a again. Enter M-x unbind-key and press <a> to get
rid of the `ring-the-bell' definition.
See command:	unbind-key	on how to get rid of definitions

Emacs might refuse to redefine a key for you if the key is special to the
current editing mode.  For example, if you are reading this in Browse mode
(check the mode line!), the <f> key acts as the Browse key that finds help on
whatever topic the cursor is on.  F3 will refuse to change the key for you,
since it is specific to the Browse mode. It will suggest that you use
M-x ef Browse-mode to change the key.  If you do, that puts you in a buffer
with the following text:

Name:F:Browse-mode
#(F:Browse-mode) re-enters Browse mode in the current buffer.
Browse mode is used to read documentation files.
[*]#(==,##(buffer-mode.#(ba,-1)),Browse,(
#(Fexit-mode)#(an,Entering Browse...)
#(ds,local-mode-changes,(#(Fmessage,Exiting Browse...)#(sv,im,.)))
#(Fk,f,F:browse-f)#(Fk,Return,F:browse-newline)#(Fk,M-Escape,F:browse-quit)
#(Ff,k-hook,(#(Fga,Fbrowse-k-hook)))
#(n?,Pstaydown,(#(Ff,Pstaydown,(#(Fga,Fbrowse-staydown)))))
#(Fmodename,Browse)),(#(Ferror,Browse mode refused for this buffer)))
[*]

The above Mint code sets up the Browse mode for reading help files. If you
would delete the part `#(Fk,f,F:browse-f)' and press C-c C-c, it would get
rid of the local definition of the <f> key. Returning to Browse mode using
F1 F1, you could now redefine the <f> key with F3.

On the other hand, if you would replace F:browse-f with F:ring-the-bell in the
above Mint code, the <f> key would ring the bell whenever you are in Browse
mode.  It would act normal (insert an f) in other modes.


			= Basics of Mint =
-------------------------------------------------------------------------------

This topic discusses how to change Freemacs itself.


Example:
--------

To see how you can change Freemacs, let us take a very simple example.
The C-x C-u command converts the region from cursor to mark to uppercase,
but first it asks:
	Region to uppercase Y/N?
We will change this question to
	Uppercase Y/N?

First determine what the name of the command to change is:
	F1 K C-x C-u
shows that C-x C-u executes command F:uppercase-region.

To edit this command (don't do it yet), use
	M-x ef F:uppercase-region
When you issue this command, you will be put in a buffer *mint-edit* with
the following paragraph of text:

Name:F:uppercase-region
C-x C-u			        Convert the selected region to uppercase
#(F:uppercase-region,OK?) converts the selected region, from cursor to mark,
to uppercase.
If OK? is nil, it confirms.
The mark can be set using C-@ or the mouse menu.
[*]	#(Fh,SELF)#(Fregion)#(Fconfirm,Region to uppercase,(
#(tr,#(Fmark),##(Fxlat-upper))),,arg1)#(Fh)
[*]

The actual Mint definition of F:uppercase-region follows the documentation
and is enclosed between [*] and [*].  You can then change the prompt in the
third line from the bottom to
	Uppercase
and press
	C-c C-c
to make to change effective.

You can try the M-x ef F:uppercase-region command now if you want.
Use C-Pg Up or F1 F1 to return here.

Now that you have a BS in Freemacs, it is on to graduate school.  To make more
complicated changes, you need to learn some more about how Mint is being
processed.  The remainder of this topic gives a brief introduction to various
Mint commands.  A full description of all Mint commands is also available,
See subject:	Mint
Finally you can always look at existing Mint code using the M-x ef, M-x ek,
and M-x grep commands.


Simple Mint Code:
-----------------

Mint is a string based language.  Here is a simple example of Mint code:

	The sum of 1 and 2 is #(++,1,2).

Freemacs has a convenient way to try out a single line of Mint code
such as this: position the cursor anywhere in the line and press F2.
Go ahead, try out the Mint code in the indented line above. From now on
you are expected to try all indented lines in this way.

When you did, you noticed that most of the line was unchanged: the result
of ordinary text is simply the text itself.  But the sharp, #, followed by
a left parenthesis introduced a Mint function.  In this case, the ++, add,
function, that adds the next two arguments.  The closing parenthesis ends
the function. The final point was again unprocessed.

Ordinary text for Mint consists of most but not all characters. Special
characters are tabs, parentheses, commas, new-line sequences, and all
graphic characters.  For now we will avoid those.

Everything is a string to Freemacs.  Try the following two examples:

	#(++,1,2)9
	#(++,#(++,1,2)9,1)

What happened here?  Well, Freemacs encountered the first #( and started
collecting the arguments of the add function.  But in doing this, it
first encountered the second add that results in 3. This was immediately
followed by a 9, and to Freemacs, a 3 and a 9 makes the number 39. When it
added 1 to that, it ended up with 40.  The point is that Freemacs does not
worry what the 3 came from.

Freemacs is not really designed to do much computation.  So most of the
build in functions perform other tasks than juggling numbers.  Try:

	#(an,You are doing great!)	#(Fpause)	Hang in there!

The #(an) `announce' primitive puts the argument following #(an, at the
bottom of the screen. The F2 key puts its result there too, but the Fpause
function puts in a slight delay, so that you can see the announcement before
it is erased by F2.

The `an' and `Fpause' do not produce any resulting string: they are
designed to produce a side effect (showing something at the bottom of the
screen, and creating a delay.).  Many Mint functions are like that: the
important thing is what they do, not what they produce.  The following line
does not produce any final result but it does ring the bell:

	#(bl)

You might ask how we can make Mint code return the string `#(bl)' instead of
ringing the bell.  The solution is to `protect' #(bl) by enclosing it with a
pair of parentheses:

	(#(bl))

When Freemacs encounters a parenthesis not preceded by a sharp, it scans
forward until it finds the matching closing parenthesis. It takes any
intermediate text at face value.

If there is no closing parenthesis, Freemacs is in trouble:

	(#(bl)

Too many closing parentheses is often less bad:

	(#(bl)))


Defining Strings:
-----------------

Mint gives you the important option to define strings.  You could not do much
with it otherwise. Let's define one:

	#(ds,my-string,Quo vadis)

You just created your first string, my-string, containing `Quo vadis'.  The
`get string' primitive gs gets the contents:

	#(gs,my-string)

Usually, you can omit `gs,':

	I say: #(my-string)?

Since my-string is not a build-in function, Freemacs assumes that my-string
is a string you want to get.

What if you named your string gs instead of my-function?  In that case the
last method would not work: Freemacs always first looks whether there is a
build in primitive function before it will try to find a user-defined function.
So it would execute the build in function gs, instead of get your string gs.


Partial Strings:
----------------

What if you have defined a string like my-string;

	#(ds,my-string,Quo vadis)

and you want to look at it a character at a time? Try the following example 3
or 4 times:

	#(go,my-string)

You see that the `get one' primitive go returns the characters of the string
one at a time. Now try

	#(my-string)

This only returns the characters not returned by `get one'.  To get back the
full string, use the `restore string' primitive rs:

	#(rs,my-string)
	#(my-string)

Each Mint string is created with a string pointer that indicates where Mint
will start reading the string. Initially the string pointer is at the start
and Mint will read the complete string.  But a primitive like get one moves
the pointer past any characters it returns.  A similar primitive is `get n'
that gets a number of characters:

	#(gn,my-string,5)
	#(my-string)
	#(rs,my-string)
	#(my-string)


Searching Strings:
------------------

Let's define another example:

	#(ds,my-motto,To be or not to be)
	#(my-motto)

To get the words out one at a time, we can look for the space characters
using the `first match' primitive.  Try to read my-motto word by word using
the next example several times with F2:

	#(fm,my-motto, )

That did not quite work, did it?  Since #(fm,my-motto, ) searches my-motto
for spaces, it is in trouble with the final `be' that does not end in a
space.  We can fix it up by specifying a third argument to fm. This specifies
what to do if the search fails:

	#(rs,my-motto)
	#(fm,my-motto, ,(#(gn,my-motto,100)))

The gn function gets the rest of my-motto if the search fails.

Note that we protected the gn function by enclosing the third argument by
parentheses: we want it to be executed only when the search fails, not
each time that Freemacs is reading the arguments of the fm function.
Arguments are often protected if they are not ordinary text.


Functions:
----------

Here comes your first function, a string that performs some useful task. We
will define show-time to flash the time and date at the bottom of the screen:

	#(ds,show-time,(#(an,#(ct))#(Fpause)))

The `current time' primitive ct returns date and time. Try it:

	#(show-time)

You just created your first function.  Pretty good, but there are some
details to be worked out.

For one, M-x show-time won't work.  M-x is picky and it only accepts strings
with names that start with an uppercase library letter that it recognizes.
That letter must also be followed by a colon.  For similar reasons, F3 won't
bind show-time to a key.

You can fix this by changing the name show-time to U:show-time.  The letter
U is a library letter that M-x recognizes; it stands for the user library
user.ed.  So, the following lines define a show-time command:

	#(ds,U:show-time,(#(an,#(ct))#(Fpause)#(an)))
	#(ds,Umodified)

Defining Umodified causes Emacs to save the string U:show-time to disk on exit.
(First it confirms that you want to save the modified editor.)

This way of defining functions does work:

	#(U:show-time)

However, you should not define functions in this way.  The proper way to
do it is with M-x give-name Return U:show-time.  That puts you in a buffer
*mint-edit* with an empty definition:

Name:U:show-time
[*][*]

Then you put #(an,#(ct))#(Fpause)#(an) between the [*] and [*] and press
C-c C-c to define. For one thing, this method allows you to define functions
that are more than a line long.


Comparing Strings:
------------------

A programming language needs to be able to compare things and take action
depending on the outcome. Freemacs can compare strings. The next examples
compare the string Abc to itself and to ABC:

	#(==,Abc,Abc,Equal,Different)
	#(==,Abc,ABC,Equal,Different)

Freemacs can also compare the magnitude of numbers:

	#(g?,8,5,Yes: 8 > 5,No: 8 <= 5)
	#(g?,2,5,Yes: 2 > 5,No: 2 <= 5)


Recursion:
----------

Mint does not have a build in looping primitive. (There is a Floop defined
function, however). It has something much better: recursion. Let's write
a little program that keeps looping until you press a key:

	#(ds,U:keep-time,(#(an,#(ct))#(==,#(k-see),Timeout,(#(U:keep-time)))))

The k-see defined function returns Timeout if no key is waiting.  U:keep-time
announces the current time; then, if no key is waiting, it invokes itself and
everything repeats. So it keeps executing until a key is pressed. Try it:

	#(U:keep-time)

Hit an arrow key or C-g to stop.


Arguments:
----------

The need for one more capability of Mint will become evident from the
following example.  It insert -*-*-*-*-* into the buffer at the cursor.

	#(ds,U:multi-insert,(#(Floop,(#(is,-*)),5)))

The `insert string' primitive function `is' inserts its argument, here -*,
in the buffer. The Floop defined function repeats its first argument, here
#(is,-*), the number of times specified in the second argument. Try it:

	#(U:multi-insert)

But what if you wanted to insert -* 30 times instead of 5, or if you wanted
to insert ` Hello' 3 times.  You could not possible write a function for
each possible case.

Function arguments to the rescue.  They are much like the arguments %1, %2,
etcetera, in DOS batch files.  But by convention, in Mint they are denoted by
arg1, arg2, ..., arg9.  Here is the example using arguments:

	#(ds,U:multi-insert,(#(Floop,(#(is,arg1)),arg2)))

Now we take out the strings arg1 and arg2 and replace them with parameter
markers.  This can be done with the mp `make parameter' primitive:

	#(mp,U:multi-insert,,arg1,arg2)

Notice that we left the second argument of mp empty.  Now U:multi-insert
can insert different strings any number of times:

	#(U:multi-insert,*-,10)
	#(U:multi-insert, Hello,3)

If you would have created U:multi-insert properly with M-x give-name,
pressing C-c C-c would take care of putting in the actual parameter markers.

How about that missing argument in the mp primitive? Well, our previous
string U:keep-time is usually defined in the following way:

	#(ds,U:keep-time,(#(an,#(ct))#(==,#(k-see),Timeout,(#(SELF)))))
	#(mp,U:keep-time,SELF)

Instead of repeating the name U:keep-time, we used SELF.  Then with the mp
primitive we replaced SELF by a `zeroth parameter'.  When we invoke a
function, the zeroth parameter is always replaced by the name of the
function.  Try it:

	#(U:keep-time)

Use of SELF makes it easier to change the name of a function.  It also
saves a lot of memory, since the function name is replaced by a single
parameter.

Could we replace the SELF parameter by something else?  If we substituted
Fpause for this parameter, U:keep-time would announce the time, pause, and
exit, instead of repeating itself.  We can do it if we go back to our gs
`get string' primitive.  We said before that #(U:keep-time) is the same
as #(gs,U:keep-time): Freemacs assumes the gs primitive if it cannot find
one.  We lied. There is a slight difference; the gs allows the SELF parameter
to be specified explicitly. Try:

	#(gs,U:keep-time,U:keep-time)
	#(gs,U:keep-time,Fpause)


Editing Strings:
----------------

The make parameter primitive mp also allows you to change selected parts of a
string: make them into parameters and then specify the desired parameters:

	#(ds,my-motto,To be or not to be)
	#(mp,my-motto,,not)
	#(my-motto,NOT)

To really put in the desired contents, simply redefine:

	#(ds,my-motto,#(my-motto,NOT))
	#(my-motto)


Neutral Strings:
----------------

Let's have another look at U:keep-time.

	#(ds,U:keep-time,(#(an,#(ct))#(==,#(k-see),Timeout,(#(SELF)))))
	#(mp,U:keep-time,SELF)

Invoking U:keep-time executes it: Freemacs gets the string and processes it.
But to see what the definition of U:keep-time really is, we would like to
make Freemacs get the string WITHOUT processing it.  We can tell Freemacs not
to process a string by putting two sharps in front of the function evocation
instead of one

	##(U:keep-time)

This still puts the name of the function as the zeroth parameter. To show how
U:keep-time was originally defined, use

	##(gs,U:keep-time,SELF)

If you want to dump the contents without any processing at all, you can
use the gn primitive:

	##(gn,U:keep-time,100)	#(rs,U:keep-time)

You see that parameters are actually represented by extended characters.

Neutral functions have other uses; they allow you to deal with unmatched
parentheses.  Mint does not like unmatched parentheses; try

	( is a left parenthesis.

You can display this line with F2 using a neutral function:

	##(bc,40,d,a) is a left parenthesis.

The base conversion function bc converts base.  In this case we converted
the number 40 from a decimal number (d) to an Ascii character (a); this
produces an open parenthesis.  By using a neutral invocation of bc, we told
Emacs to return the parenthesis without processing it any further.  After all,
we don't want to start protecting text.

Any general user input in Freemacs is evaluated neutral, since an input might
involve unmatched parentheses at any time.

The next example inserts an unmatched parenthesis at the cursor:

	#(is,##(bc,40,d,a))

Without the neutral function, there would be no way to do it.

Remember U:multi-insert?

	#(ds,U:multi-insert,(#(Floop,(#(is,arg1)),arg2)))
	#(mp,U:multi-insert,,arg1,arg2)

Let's use it to insert 10 left parentheses in the buffer.  Guess which
of the next examples works:

	#(U:multi-insert,(,10)
	#(U:multi-insert,##(bc,40,d,a),10)
	#(U:multi-insert,(##(bc,40,d,a)),10)

The first one does not work because Freemacs is not even able to read the
shown line.  In the second example, Freemacs reads the invocation correctly
and decides that it wants to execute the function U:multi-insert with arguments
( and 10.  So it pushes ( and 10 into the U:multi-insert string and tries to
process that.  But alas, this string now has an unmatched left parenthesis,
and Freemacs cannot read it either.  In the third example, the bc function is
protected when Freemacs first reads the line.  So Freemacs now decides that it
wants to execute function U:multi-insert with arguments ##(bc,40,d,a) and 10.
It pushes ##(bc,40,d,a) and 10 into U:multi-insert and that works.

A rule of thumb: if an argument may have special characters, protect it
and evaluate it only at the last possible moment.

Using ##(bc,N,d,a), we can create parentheses (codes 40 and 41), comma (44),
tab (9), new-line (##(bc,13,d,a)##(bc,10,d,a)), and extended characters
(codes greater than 127). For tabs, commas, and new-line it is usually easier
to protect the actual characters; compare

	#(U:multi-insert,(##(bc,40,d,a)##(bc,9,d,a)##(bc,44,d,a)),2)
	#(U:multi-insert,(##(bc,40,d,a)(	,)),2)


Managing Strings:
-----------------

Let's have a look at some functions that maanage strings such as

	#(ds,my-motto,To be or not to be)#(ds,my-string,Quo vadis)

The `list strings' primitive is ls:

	##(ls,|,my)
	##(ls, ,U:)

It lists all strings starting with the third argument, separated by the
second argument.

If the third argument is empty, it lists the names of all strings.
WARNING:  if you have a MEMORY LOW message in the mode line, exit Emacs
and re-enter before proceeding:

	##(ls)

How many characters is that?  Well, the `number of characters' primitive nc
will tell you:

	#(nc,##(ls))

The `erase string' primitive es erases one or more strings:

	##(ls,(,),my)
	#(es,#(ls,(,),my))
	##(ls,(,),my)

The second argument of ls was a protected comma.

Just for laughs, figure out what the next example would do:

	#(es - don't do it! ,#(ls,(,)))


Marks:
------

Marks are locations in the buffer indicated by one-character names.

Put the cursor at the start of the next line and try it several times:

	#(sp,>)

The `set point' function sets the cursor (point) to the location given
by the mark in the argument.  The system mark > indicates the next character,
< the previous one, [ the start of buffer, ] end of buffer, . the current
location of the cursor and so on.

There are also user marks that can be set at any point of the buffer and
later be used to return to that point.  In the next example, the second line
will return the cursor where it was when you executed the first line:

	#(sm,A,.)#(sp,$>$)
	#(sp,A)

The first line sets mark A at the cursor using the `set mark' sm primitive.
Next it moves cursor in succession to end-of-line, the next character on the
next line, and the end of that line.  The second line returns the cursor to
mark A.

The above global user marks, the @ character and A through O, are available
to the user with C-@ and other commands.  So if you write Mint code, you
usually want to leave these marks alone.  Fortunately, there is a second
type of user marks, called local, that can be allocated on the fly, used,
and deallocated again.  The following example returns the cursor to a
previous line, (this line), announces it, and resets the cursor:

	#(pm,1)#(sm,0,.)#(sp,^<^<^)#(an,##(rm,$))#(Fpause)#(sp,0)#(pm)

There is a lot here.  First, the `put mark' function #(pm,1) allocates one
local user mark, the mark 0.  Then #(sm,0,.) puts mark 0 at the cursor;
this is the default and could be omitted.  The #(sp) function puts the cursor
at the second last line by a succession of putting the cursor at the start of
a line and then one character back.  The `read to mark' function rm reads
the line from cursor to end-of-line (note the neutral invocation). After
a pause, we put the cursor back and deallocate the local mark with #(pm).

Do not forget to deallocate the local marks, or Freemacs will flip out.


Searching:
----------

The following example illustrates a search. It searches backward for the
string `Abc', then returns the rest of the line:

	#(pm,2)#(lp,Abc)#(l?,.,[,1,,(#(sp,1)##(rm,$)))#(sp,0)#(pm)

Try F2 both with the cursor at the start of the line and at the end.

In the above example, the `look pattern' primitive lp sets the string to look
for.  The `look' primitive `l?' actually searches.  Its arguments specify
what region to search and what to do if the string is found.


Conclusion:
-----------

This topic showed you some of the basic Mint commands.  There are many more
Mint primitives, dealing with files, colors, libraries, and so on.
See subject:	Mint		for a complete listing of all primitives

The next topic shows some important aspects of the wide world of Mint.
See topic:	Mint Library

Remember that you can edit any defined Mint function with M-x ef to look at the
source and docs.  The M-x grep command allows you to find all occurrences of a
string.


			      = Mint Library =
-------------------------------------------------------------------------------

This topic summarizes the commands that allow the editing of functions.

Initialize:
-----------

			Go to the edit buffer
See command:		strings-edit

			Force Mint mode (Automatic for .min files)
See command:		Mint-mode

Execute:
--------

			Execute a Mint function
See command:		x

M-Escape		Execute a buffer of Mint code
See command:		execute-buffer

Edit:
-----

			Create a new function
See command:		give-name

			Edit selected functions
See command:		ef

			Edit a key definition
See command:		ek

			Edit all key definitions
See command:		keys-edit

			Edit all loaded options
See command:		edit-options

C-c C-c			Read the changed functions back in
See command:		done-editing

Debug:
------

			Search all functions for a string
See command:		grep

			Trace the invocations of a function
See command:		trace

			Stop tracing
See command:		untrace

			Stop all tracing
See command:		untrace-all

			Cross reference a (small!) library
See command:		cref-lib

			Compare the modified functions with the .ed file
See command:		compare-ed

Syntax:
-------

			Edit the syntax table
See command:		syntax-edit

			Read the modified syntax table
See command:		syntax-read

			Recover the default syntax table
See command:		syntax-recover

Manage:
-------

			Create a new edit library
See command:		create-library

			Remove erroneous docs
See command:		remove-nonexistant

Erase:
------

			Erase a function
See command:		erase-string


			       = Mint Notes =
-------------------------------------------------------------------------------

This topic gives some general notes about Mint programming.  Skim through it
and consult it when needed.


Reserved Names:
---------------

There are some names that should not be redefined.  They include the three
single letter names d, g, and k that should never be redefined.  To avoid
accidentally using such a name, it is a good idea to start your strings
with a unique identifier such as my-.  Or start strings with a U to put
them in the user library user.ed.  Anyway, save often.

If you want to check whether a string exists, use the ls primitive or M-x ef.

Names starting with a capital, such as Fpause, belong to a library.

For reference, below is a list of names used by Freemacs that do not start
with a capital.

cd-err	Defined when #(sv,cd,) fails, used to reset cd after a missing floppy.
d	Executes the key pressed by the user.
g	Inputs the next key.
g-it	Gets the next key from the keyboard.
g-do	Task to perform on receiving the next key, such as clearing the screen
k	Rewrites the screen.
k-see	Looks whether a key is waiting.
key	A user key stroke as obtained by Fkey.
keyl	Lower case conversion of key obtained by Fkeyl.
path	Path to file spec.
result	Result of the last #(d) command which executes the user keystrokes.
spec	A cleaned up file specification returned by Fabsolute-filename-do.
value	Default value for an Freadline input operation and its result.
[...]-hook	A modifiable part of a function.
abbrev.[...]	Abbreviations
buffer-[...]	Stored variables for a given buffer.
default.[...]	Default value for an Finsist value.
deleted-char	The last character deleted.
error-buffer	Buffer with the compilation errors.
error-handler	Reads the errors.
g-do-always	Task to perform at the input of each key.
global-modes	Global editing modes such as DEF or RUN.
help.[...]	Help topics
isearch-count	What occurrence of a string to search for.
kbd-macro	The latest set of stored keystrokes.
kbd-buffer	Set of stored keystrokes being played back.
lib-name	The capital letter stored in a library.
lib-list	A list of loaded library letters.
line-offset	The amount of lines to add to the error line number.
mark.[...]	The current mark for a given buffer number.
minor-modes	Buffer-specific editing modes such as Text, Overwrite, etc.
old-buffer	Default buffer to return to.
other-window	Buffer number selected in the other window
read-only	Buffer is read-only
source-buffer	Source of the code compiled last
suspended-DEF	indicates an interrupted keyboard macro definition.
suspended-RUN	indicates an interrupted keyboard macro execution.
trace-buffer	Buffer number for M:trace output.
trace-indent	Indentation of M:trace output.
trace-result	Result of a traced command.
traced-[...]	Variables traced using M:trace.
abbrevs-modified	Whether new abbrevs have been defined.
local-mode-changes	Commands to restore the editor on exiting the buffer.
rectangle-buffer	buffer number of the last cut rectangle.
speller-modified	Whether words have been added to the dictionary.

Temporary names:
.t0, .t1, .t2, ..., tmp, temp.  by various commands
.[Some capital letter][...]     by various commands
[...].list, [...].element       by Fmultiple
[...].lib-list		        by Ffor-all-libs


Functions:
----------

Function names that start with a capital letter belong in the library of
that capital.  The currently defined library letters are:
A (Abbrev), B (BibTeX), C (C), D (Dired), F (Emacs), K (Keys), L (Lisp),
M (Minted), N (Fortran), P (Mouse), T (TeX), U (User).
It is a good idea to start your functions with U so that they will be saved
in files USER.ED (the function) and USER.EDD (the docs).

Use a colon as the second character of the name if you want the user to be
able to call the function directly with M-x or bind it to a key.

Start the function with a Tab character if it is to use any C-u argument
provided by the user.  If you do not provide a Tab as first character, C-u
repeats the function a specified number of times.


General Purpose:
----------------

This subtopic lists a few general purpose defined functions.  Use as needed.
Examine the source using M-x ef.

Fbackward-skip		Move backward, executing something
Fblank			Examine whether a character will show
Fcase			Classify a case
Fconfirm		Prompt the user before proceeding
Fcompleting-readline	Read a string with input completion
Fenter-global-mode	Set a global mode
Ferror			Announce an error
Ffind-a-match		Examine a list of strings
Fforward-skip[-ct]	Move forward, executing something
Ffm			Expanded fm primitive
Fg-wait			Peek at the next key
Fga			Return the exact contents of a string
Fgar			Return the exact contents of a redefined string
Fgoto-row-and-column	Position the cursor
Fhit-any-key		Ask the user to hit a key
Fin-global-mode		Examine whether a global mode is active
Finsist			Prompt the user if an argument is missing
Fis-upper		Upper case?
Fkeyl			Get a key from the user
Flines			Show the selected lines
Flm			The `last match' function
Fload-letter		Loads the library corresponding to a capital letter
Flocation		Show the cursor location during I/O
Floop			Loop
Fmark			Return the currently selected user mark
Fmax			Maximum of two numbers
Fmessage		Announce an informational message
Fmin			Minimum of two numbers
Fmore			Show a lot of info to the user
Fmultiple		Execute a function multiple times
Fpad-to-column		Insert tabs and spaces as needed
Fpop-mark		Select another user mark
Fpresent		Search for a string
Fprotect		Protect a string
Fread-key		Get a complete key sequence
Freadline		Read a string
Fredefine		Redefine a string temporarily
Fregion			Show the selected region
Fright			The last characters of a string
Fsave-lib		Saves a library
Fshell			Execute a DOS shell
Fspaces-to-tabs		Convert spaces into tabs
Ftabs-to-spaces		Convert tabs to spaces
Fto-upper		Case conversion
Fwhite			Examine if a space or tab
Fwhitespace		Next character does not show?
Fyes-or-no		Prompt the user for Yes or No


Initialization:
---------------

Emacs starts up by loading emacs.ed from the directory specified in the
environment variable EMACS. Immediately after loading emacs.ed, F&setup is
executed.

F&setup first reads in the environment variables as env.EMACS, env.COMSPEC, ...

Next it initializes the list of loaded libraries and the global modes.

It defines k, which rewrites the screen and updates the mode line if time is
available, through Fredisplay-one.
It defines d, which executes user keystrokes, equal to the Fd function.
It defines g, which inputs all keys, equal to the Fg function.

It sets the syntax table, which defines word boundaries, equal to Fsyntax.

It sets various defaults to show trailing whitespaces, 20% screen margins that
scroll, and auto-save action after #(F-auto-save) key motions.
It sets the foreground and background colors to F-fore-color and F-back-color.

It initializes the cut-and-paste buffer 1 and inserts 9 bars with marks on them.
Initializes minor-modes to nil and buffer-mode.1 to Fun.

Next it loads all libraries mentioned in F-libs-to-load; this must include keys.

Finally F&setup processes the command line used to run emacs:
If it contains 'continued', F&setup loads and executes $-emacs.ini from the
default directory.
Otherwise, the command line should contain file specifications separated by
commas, spaces, tabs, or plus signs, that are loaded one by one. Wildcards are
permitted.

Use M-x ef to edit F&setup, but do not damage it; if it does not load keys,
you cannot do any editing. You might have to restore emacs.ed from emacs.tmp.

Buffers:
--------

This subtopic gives a brief description of the setup of edit buffers.

The ordinary buffers have numbers B starting from 2 onward. The buffer can be
selected using #(ba,B), after which #(ba,-1) returns B.

The data available for each buffer B are:
buffer-number.B		Contains the buffer name BUFFER.  When the buffer is
			associated with a file, BUFFER ordinarily contains the
			filename of the file.  However, where needed, BUFFER
			is made unique by appending a serial number, (<2>, or
			<3>, or ...).
			Name BUFFER cannot include commas or @ characters.
			Start the names of work buffers without files with `*'.
buffer-name.BUFFER	Contains the buffer number B.  This is the inverse of
			buffer-number.B.
buffer-filename.B	Contains a full, clean pathname for the file being
			edited in the buffer.  Does not exist if the buffer has
			no file.  Top directories are in the form 'd:'
			followed by an arg2 parameter marker, and lower level
			ones, eg, 'd:\sub' followed by an arg1 marker.
buffer-mode.B		Contains the major mode of the current buffer, (Fun,
			Mint, Dired, Buffer Menu, Fortran, TeX, ...).
			For each mode, there should be an F: initialization
			function, (F:Fun-mode, F:Mint-mode, F:Dired-mode, ...)
			which exits any existing mode using Fexit-mode, and
			sets the major mode name using Fmodename.
			The mode name should not include commas, tabs, or
			parentheses, and also no points if it is to be the
			default mode for certain file types.
buffer-minor-modes.B	Contains the current minor modes of the buffer.
			Minor modes cannot include unmatched parentheses.
buffer-vars.B.NAME	Contains a local value for name NAME.
			NAME cannot include parentheses, tabs, or commas.
			buffer-vars.B.NAME cannot contain unmatched parentheses.
mark.B			The current mark for the buffer (@-O).

For the current buffer we have
minor-modes		Contains the current minor modes of the buffer.
local-mode-changes	Contains the commands which will restore the locally
			re-defined keys and names back to their original value.

For all user buffers we have:
last-buffer		A list of active user buffer names, each preceded by @
			and terminated by a comma.
			Buffers not in this list are not saved by C-x s:
			for example, .edd extensions should not be in the list.

To create a new buffer:
#(Ffind-unused-buffer,(BUFFER)) fully defines a buffer:
	creates and selects a buffer,
	executes #(Fbuffer-set-name,(BUFFER)) which
		sets buffer-name and buffer-number
		erases buffer-filename
	sets buffer-mode to Fun
	executes #(Fenter-local-modes-do) which
		executes #(Fexit-mode)
			resetting minor-modes and local-mode-changes
		sets buffer-minor-modes.B, minor-modes, local-mode-changes

If you want to associate this buffer with a file:
#(Fvisit,(SPEC))
	trashes the current buffer contents
	executes #(Fbuffer-set-fn,(SPEC)) which
		sets buffer-name, -filename, and -number
	loads the file SPEC
	sets buffer-mode from any info in the file or from the file type
	executes #(Fenter-local-modes-do) which
		sets buffer-minor-modes.B, minor-modes, local-mode-changes

Unless this is a work buffer, you will want to add it to the last-buffer list
of buffers using:
#(Fremember-buffer)

To destroy a buffer:
#(Fkill-buffer)
	exits any current mode
		resetting minor-modes and local-mode-changes
	trashes the current buffer contents
	executes #(Fbuffer-set-name) which
		erases buffer-name, -number, and buffer-filename
		and resets last-buffer
	erases buffer-mode, -minor-modes.B, and -vars.B....
	selects another buffer

Some important other functions for buffers are:

Fset-minor-mode		Set a minor mode such as Fill, Indent, ...
Fin-minor-mode		See whether a minor mode is set
Fbuffer-modified	See whether the buffer has been changed
Fk			Define a local key
Ff			Define a local function
Flocal-bind-var		Define a local variable
Ffor-all-buffers	Perform a task for all buffers


Libraries:
----------

All strings starting with a given capital, say L, are saved to disk as file
##(Lfilename).ED.  The documentation is saved in file ##(Lfilename).EDD.
This is done by Fsave-lib. (Executed on exit, provided name Lmodified has been
properly defined.  M:done-editing will take care of that.)

Fsave-lib also saves the library letter L in the file as string lib-name, so
that the library letter of a newly loaded library is easily determined.
Fload-letter or Fload-lib load libraries from disk back into memory.  They
execute L&setup afterward, which allows you to perform any initialization
required for the library.

The very first string to define for a new library letter L is Lfilename.  It is
also a good idea to update option F-lib-files.



I/O:
----

This subtopic gives a brief description of the Freemacs I/O system.

Much of the initialization is done within function F&setup that initializes
Emacs.

Standard operation of Freemacs depends on 3 elemental functions; d, g, and k.
	g gets a keystroke from the keyboard
	d processes a keystroke
	k updates the screen
Essentially, Freemacs works by performing an infinite sequence
... #(k) #(d,#(g))   #(k) #(d,#(g))   #(k) #(d,#(g)) .....

WARNING: if g, d, or k is broke, the editor is disabled.  You might have to
reboot if this happens.  And if you managed to save a defective g, d, or k,
you might have to restore an old file emacs.ed from emacs.tmp or from your
last backup.

Function d executes the user's key strokes. In it simplest form, it would
insert the pressed key KEY into the buffer unless a function K.KEY exists,
in which case that function is executed instead.

For example `a' would ordinarily be inserted in the buffer, since K.a is not
defined.  But `C-f' would move the cursor one character forward, since K.C-f is
defined as `F:forward-character'.

A possible form for d would be:
	#(n?,K.arg1,(#(#(K.arg1))),(#(Fself-insert,arg1)))
The actual d, stored in function Fd, in addition defines a string `result' to
hold the result of the key execution.  String result can be examined when the
next key is being processed.  Extended characters are not allowed in result.

Function g gets the next key. Its simplest form would be `#(it,TIME)' where
TIME is the time to wait before returning `Timeout' as the key to process.
TIME cannot be infinite, the maximum possible is 65535 (default), which is
about 11 minutes. Timeout will ordinarily be ignored by function d, but you
could be creative and produce a message such as `Back to work, please.'

However, the actual form of g is more complex for a number of reasons:
- We may want to erase a message or restore the screen when the user presses
  the next key; this is achieved by passing the key through a function Fg-do.
- We may want to store the user's keystrokes so that they can be played back
  without the user having to retype them all; Fg-store is used here,
- We may want to play back the stored keys; this trick is performed by
  defining a more basic form of g, called g-it, that actually gets keys from
  the keyboard.  Ordinarily g contains g-it and the keys are obtained from the
  keyboard.  But when playing back a stored key sequence, g is redefined
  to use a function Fg-macro that gets the stored keys instead.  When all stored
  keys have been played back, g-it is pushed back into g.
We also want maximum response if we are not waiting for keys or playing back
stored keys, since the user may hold down an arrow key, and we need to keep
up with all those keystrokes.

To achieve these objectives, F&setup initializes g essentially as:
	#(Fg-store,#(Fg-do,arg1arg2,do),store)
and then removes Fg-store and Fg-do by replacing them with parameter markers.
Then it shoves g-it in between the arg1 and arg2 markers.  The net result of
all this is that g contains g-it surrounded by a cloud of parameter markers.
Function g-it equals `##(it,65535)'.

If we want to execute anything when the next key is input, we define Fg-do
to perform the task, and put the call to Fg-do back in g by filling in the
parameters. This is done by Fon-key.

If we want to start saving keys, we restore Fg-store in g. This is done by
F:start-kbd-macro.

If we want to start playing back stored keys, we take g-it out from
between arg1 and arg2 and shove in Fg-macro. Fg-macro gets the stored
keys one at a time.  See F:execute-kbd-macro.

When saving keys, they are stored in kbd-macro.  When playing them back,
they are first copied into kbd-buffer which is then read a key at a time
by Fg-macro.  A simple compression scheme keeps the sizes of kbd-macro and
kbd-buffer in check.

As far as the function g-it is concerned, this function always gets keys
from the keyboard.  But sometimes we need to get a key KEY from the keyboard
without formally inputting it.  The reason is to create a wait time.  If we
do this, we must keep KEY pending until it is formally input.  That is done by
redefining g-it to `KEY	#(Frestore-gk)' so that if we call g-it the second time
for real, it will return KEY as well as execute #(Frestore-gk).  Frestore-gk
restores the ordinary g-it to g and resets the function k-see described below.
See Fpause.

The final elemental function is k which updates the screen.  The simplest form
for k would be `#(rd)#(Fmode-line)' to update both the visible part of the
buffer as well as rewrite the mode line to show the new cursor position, etc.
But to prevent that Freemacs would not keep up with the user's keystrokes, the
mode line is only updated if a function k-see verifies that no key is waiting
by returning Timeout.

The actual form for function k can be found in Fredisplay or Fredisplay-two.
The function k-see is more complicated; it has four possible forms to take care
of different states of functions g and g-it:
	##(it,0)
	##(it,0)K
	RUN
	RUNK
The first form is the standard way of checking the keyboard.  A trailing K
indicates that a key has already been informally input, as described above
for g-it.   If we are running a keyboard macro, ##(it,0) is replaced by RUN.

A tricky issue is that if the keyboard macro is empty, it is only observed
when the next key is input.  Thus k-see might not return Timeout, even if
no key is available for processing.  Fg-see will always return the correct
key waiting, but is much slower than k-see.

Some important higher level I/O functions are:

Freadline		Get an input line from the user
Fcompleting-readline	Get an input line from the user, with input completion
Fread-key		Get a key stroke from the user
Finsist			Prompt the user if a function argument is missing
Fpause			Execute a short delay
Ferror			Show an error message
Fmessage		Show an informational message


Shell:
------

Shelling to DOS is tricky business.  Since Emacs stays in memory, memory left
for DOS may be small and something may hang.  Freemacs provides an option to
replace shelling to DOS with exit to DOS, but after saving the state of the
editor.  The user can select this option by setting F-shell-program to nil
using the menu or `M-x edit-options'.

In addition, Freemacs has some trouble recovering.  Use function Fshell to
shell, since it bypasses this difficulty.


			      = Browse Files =
-------------------------------------------------------------------------------

The Freemacs browser provides a way to read a series of documentation files.
The files are written such that they can be easily understood even without the
browser.  The *.hlp files in the Emacs directory provide an example of such
documentation files. The file you are reading right now is one of them.

If you want to use the Freemacs browser to provide a way of browsing through
your own documentation files, you should study the *.hlp files in the emacs
directory for the required format.

Or, if you want to change or add to Emacs help files, look here for the format.

File Format:
------------

To allow moving back and forward, Browse needs a certain format to the files
it reads.  It needs headers to locate and directions how to locate them.


Headers:

Headers indicate the start of a part of the documentation. There are 5 levels
of header:

Subjects:
Subject headers must be valid DOS filenames.  Moving to the subject is
interpreted as `load file <Subject>.ext'.  The file extension can be changed
if you want.  For example, you are now reading MODIFY.HLP in the emacs
directory.

Topics:
Topic headers are inserted as `= <Topic> =', more or less centered on the
screen, and immediately followed by a line with at least 55 hyphens. See the
current `Browse Files' topic header above for an example.

Subtopics:
Subtopics are inserted at the start of a line, preceded by an empty line and
followed by a colon followed by a line consisting of at least 2 hyphens,
followed by a blank line.  See the `File Format' header above for an example.

Items:
Items are inserted at the start of a line, preceded by a blank line and
followed by a colon and a blank line.  See the `Headers' header above for
an example.

Subitems:
Subitems are inserted at the start of the line and preceded by a blank line
as items, but they do not need to be followed by a blank line.  See the
`Subitems' header above for an example.


Contents Tables:

Directions can be given in a contents table.  Each line in such a table defines
a subject, topic, subtopic, item, or subitem.  The lower the level of the
header, the more indentation it should be given, consisting of spaces and
hypens (no tab characters).  The highest level header in the table should not
be indented.  Regardless of level, each line must use a tab character (not a
space) to tab to column 33.  Browse uses this tab to decide whether the cursor
is in a contents table.

Before the table, a line starting with `Subjects:', or `Topics:', or ... is
needed to identify what the contents lines without indentation represent.

See the contents table at the start of this file for an example.


Pointer Lines:

Two examples of pointer lines are

See item:	Pointer Lines				Brings you back here
See subtopic:	File Format, item Pointer Lines		Brings you back here

The keyword behind the See can be subject, topic, subtopic, item, or
subitem; you do not need to specify the highest levels that are the same
at the current position. The colon must be followed by at least one tab
character. Behind the header, add further directions as appropriate in the
format `, KEYWORD HEADER', using single space separations.

Terminate the path by at least one tab character or end-of-line.


Other Requirements:

Headers must always be typed the same.  Any error in capitalization or spacing
will prevent Browse from locating it.  Headers cannot start with a space or
a hyphen, they cannot contain tab characters, they cannot end in a colon, and
they cannot contain special characters (with decimal codes 128 to 255).

You should also take care that the remaining text is not misidentified by
Browse as headers, contents lines, or pointer lines. Always check the file
by moving the cursor through it line by line in Browse mode.  The next
guidelines apply:

If you do not end lines in an equals sign or colon, there can be no confusion
about headers.  In any case, equals signs not immediately followed by a line
with at least 5 hyphens do not cause confusion.  Colons at the end of lines
not preceded by a blank line cause no difficulty either.  Otherwise, assuming
the line is not the same as an existing header, it can only cause trouble if
it is in the middle of a series of subitems and followed by a blank line.

No line can be confused for a contents line if you do not tab to column 33.
You could use spaces to do it instead.  If you do tab to column 33, Browse
will still ignore it if the first word on the line is followed by a colon,
or if the line starts with a tab.

To avoid confusion with pointer lines, do not start any line with
`See WORD:	'.

Browse Command:
---------------

To enable browsing of your files, create a file with a .min extension.
In it, put a definition of the form

Name:F:COMMAND
[*]#(Fbrowse-init,*BUFFER*,DIR,EXT)[*]

where COMMAND is the command you want to use to invoke browsing, BUFFER is the
name to use for the buffer, DIR is the directory in which you have put your
browse files, and EXT the file extension that you have given your files.  Avoid
parentheses, commas, tab characters, and graphic characters in COMMAND, BUFFER,
DIR, and EXT.  Press C-c C-c to define COMMAND.

In order for COMMAND to work, one of your browse files must be named
contents.EXT and must contain a global contents table.

************************* Use C-Pg Up to return  ******************************
************************* Use Pg Up to scroll up ******************************
*******************************************************************************
